home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DDJMAG
/
DDJ9207.ZIP
/
AVKCAPT.ZIP
/
ACAVK.C
next >
Wrap
C/C++ Source or Header
|
1992-04-03
|
28KB
|
1,069 lines
//-------------------------------------------------------------------------
// ActionMedia II Programmer's Toolkit
//
// Windows Motion Capture Sample Program
//
// Application: AvkCapt.exe
// Module Name: acavk.c
//
// description: this module contains the functions that directly reference
// AVK API functions.
//
// Copyright Intel Corp. 1991, 1992
// All Rights Reserved.
//
//-------------------------------------------------------------------------
//
// Exported functions from this module:
//
// InitAvk
// EndAvk
// ToggleMonitor
// GetDevCaps
// SetDstBox
// ToState
// IsState
// GetState
//
//-------------------------------------------------------------------------
//
// Functions local to this module:
//
// CreateCaptureGroup
// CreateVideoStream
// CreateAudioStream
// LoadVshFile
// MonitorOn
// MonitorOff
// CreateView
//
//-------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <memory.h>
#include "avkapi.h"
#include "avkio.h" // AVSS file I/O subsystem header
#define ACAVK_NOEXTERNS 1
#include "avkcapt.h" // main application header
#include "disperr.h" // error display subsystem header
#include "memalloc.h" // memory allocation subsystem header
#include "log.h"
#include "copylist.h"
extern HWND hwndMain;
extern HANDLE hInst;
extern VIDEO_SYNC Syncs[];
//-------------------------------------------------------------------------
// Local variables.
//-------------------------------------------------------------------------
static WORD State = ST_UNINITIALIZED; // current state of
// capture engine
VIEW View; // view control structure
AVIO_SUM_HDR Avio; // master control struct
// for AVSS file I/O
I16 AvkRet; // general AVK return
// code variable
WORD CaptureSync = SYNC_NTSC; // default to NTSC
char far *pVshBuf = NULL; // buffer for reading VSH data
U32 VshSize; // size of the VSH data.
CAPT Vid; // video capture
// control structure
CAPT Aud; // audio capture
// control structure
//-------------------------------------------------------------------------
// Variables for the clipping timer.
//-------------------------------------------------------------------------
FARPROC lpThunk; // instance 'thunk' for
// clip timer proc
BOOL bClipTimerSet = FALSE; // TRUE when clip timer running
COPYLIST CopyList;
//-------------------------------------------------------------------------
// RTV 2.0 encoding arguments. Used to encode captured video into
// AVSS Real-Time Video 2.0 compressed format. Note that the values
//
//-------------------------------------------------------------------------
AVK_RTV_20_ENCODE_ARGS Rtv20Args = {
12, // arg count
AVK_RTV_2_0, // alg size
0,0, // x,y coords of origin
128, 240, // xLen, yLen - fill in
3, // still period
0, 0, // Bytes,lines
AVK_RTV_20_PREFILTER | AVK_RTV_20_ASPECT_25, // flags
0, 0 // quant values
};
//-------------------------------------------------------------------------
// AVK handles.
//-------------------------------------------------------------------------
HAVK hAvk = (HAVK)0;
HAVK hDev = (HAVK)0;
HAVK hGrp = (HAVK)0;
//-------------------------------------------------------------------------
// Local function prototypes.
//-------------------------------------------------------------------------
static BOOL CreateCaptureGroup(VOID);
static BOOL CreateVideoStream(VOID);
static BOOL CreateAudioStream(VOID);
static BOOL CreateView(VIEW *);
static BOOL LoadVshFile(VOID);
static BOOL MonitorOn(VOID);
static BOOL MonitorOff(VOID);
BOOL GetDevCaps(VIEW *);
BOOL SetDstBox(HWND);
WORD ToState(WORD);
BOOL IsState(WORD);
WORD GetState(VOID);
VOID SetClipTimer(VOID);
VOID KillClipTimer(VOID);
WORD FAR PASCAL ClipTimerProc(HWND, WORD, WORD, LONG);
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL InitAvk(VOID)
//
//DESCRIPTION:
//
// Create an AVK session and open the board. After determining the
// type of monitor we have, and creating a view, we create a
// capture group with all of its resources and an image we will use to
// grab a frame from the capture group while we are premonitoring.
//
//RETURN:
//
// TRUE on success.
// FALSE on any error (error message box is displayed before exit).
//
//-------------------------------------------------------------------------
BOOL
InitAvk()
{
// Don't do if already initialized.
if (!IsState(ST_UNINITIALIZED))
return TRUE;
// Start an AVK session with messaging. Give AVK the
// client window handle for returning messages.
if ((AvkRet = AvkBeginMsg(hwndMain, &hAvk, AVK_SESSION_DEFAULT)) != OK)
return DispAvkErr(AvkRet, "AvkBeginMsg");
// Now that we have our AVK session handle, we can initialize the
// error display system and give it the AVK handle. Be sure to
// turn on date and time flags and logging to disk.
InitErrSystem(hAvk, TRUE, TRUE, TRUE);
// Open the device (board).
if ((AvkRet = AvkDeviceOpen(hAvk, 0, AVK_DEV_OPEN_EXCLUSIVE, &hDev))
!= OK)
return DispAvkErr(AvkRet, "AvkDeviceOpen");
// Lastly, get the capture sync by calling AvkDeviceVideoIn(). The
// capture sync will be returned as part of the 32-bit parameter
// for the AVK_IDENTIFY message. We will have to suspend our
// initialization for the time being and return to the message loop
// to await an AVK_IDENTIFY message with the capture sync value.
// From there, we will call CreateAvkResources() to finish
// initializing AVK for capture.
if ((AvkRet = AvkDeviceVideoIn(hDev, AVK_CONN_DIGITIZER)) != OK)
return DispAvkErr(AvkRet, "AvkDeviceVideoIn");
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL CreateAvkResources(WORD NewCaptureSync)
//
//DESCRIPTION:
//
//RETURN:
//
//-------------------------------------------------------------------------
BOOL
CreateAvkResources(WORD NewCaptureSync)
{
// We called AvkDeviceVideoIn() to produce an AVK_IDENTIFY
// message. On receipt of the AVK_IDENTIFY message, we extracted
// the source sync and then called CreateAvkResources() to finish
// initializing AVK. Set the CaptureSync variable accordingly.
switch (NewCaptureSync)
{
case AVK_SYNC_NTSC: CaptureSync = SYNC_NTSC; break;
case AVK_SYNC_PAL: CaptureSync = SYNC_PAL; break;
}
// Once the device has been opened, we can get the AVK device
// capabilities from AVK.INI
if (!GetDevCaps(&View))
return FALSE;
// Now that we have figured out the AVK screen resolution and the
// Windows->AVK conversion factors, let's set the stream
// destination coordinates.
// Create the AVK view.
if (!CreateView(&View))
return FALSE;
// Load the VSH file. This file contains data used in compressing
// the incoming motion into an RTV 2.0 file.
if (!LoadVshFile())
return FALSE;
// Create a capture group.
if (!CreateCaptureGroup())
return FALSE;
// Set the initialization flag.
ToState(ST_INITIALIZED);
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL EndAvk(VOID)
//
//DESCRIPTION:
//
// Close an AVK session by calling AvkEnd(). This also
// implicitly destroys all created objects.
//
//RETURN:
//
// TRUE on success.
// FALSE on any error (error message box is displayed before exit).
//
//-------------------------------------------------------------------------
BOOL
EndAvk()
{
BOOL Ret = TRUE;
// End the session.
if (hAvk != HNULL)
{
if ((AvkRet = AvkEnd(hAvk)) != OK)
{
DispAvkErr(AvkRet, "AvkEnd");
Ret = FALSE;
}
}
if (Vid.pBufHead)
{
MemFree(Vid.pBufHead);
Vid.pBufHead = NULL;
}
if (Aud.pBufHead)
{
MemFree(Aud.pBufHead);
Aud.pBufHead = NULL;
}
// Null out all of the AVK handles.
hAvk = hDev = HNULL;
hGrp = HNULL;
Vid.hGrpBuf = Vid.hStrm = HNULL;
Aud.hGrpBuf = Aud.hStrm = HNULL;
View.hView = HNULL;
View.hConnDigi2Strm = View.hConnStrm2View = HNULL;
ToState(ST_UNINITIALIZED);
return Ret;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL CreateCaptureGroup(VOID)
//
//DESCRIPTION:
//
// Create a Capture Group and all needed resources for premonitoring.
// In order to capture or premonitor video and/or audio from the digi-
// tizer, you must create a Group, at least one Group Buffer and
// a Video Stream and/or an Audio Stream as needed. The streams then
// must be formatted with the information on resolution, bitmap format,
// capture frame rate, VSH compression data, etc.
//
// Since the aim of this application is to grab a still image from the
// video stream, we only create and format a Video Stream here.
//
//RETURN:
//
// TRUE on success.
// FALSE if an AVK call failed.
//
//-------------------------------------------------------------------------
static BOOL
CreateCaptureGroup()
{
// Create the capture group.
if ((AvkRet = AvkGrpCreate(hDev, &hGrp)) != OK)
return DispAvkErr(AvkRet, "AvkGrpCreate");
// Create the group video and audio buffers.
if ((AvkRet = AvkGrpBufCreate(hGrp, AVK_BUF_CAPTURE, VID_BUF_SIZE,
VID_BUF_GRAN, 1, &Vid.hGrpBuf)) != OK)
return DispAvkErr(AvkRet, "AvkGrpBufCreate");
if ((AvkRet = AvkGrpBufCreate(hGrp, AVK_BUF_CAPTURE, AUD_BUF_SIZE,
AUD_BUF_GRAN, 1, &Aud.hGrpBuf)) != OK)
return DispAvkErr(AvkRet, "AvkGrpBufCreate");
// Create host RAM I/O buffers for retrieving video and audio frames.
if ((Vid.pBufHead = MemAlloc(HOST_BUF_SIZE)) == NULL
|| (Aud.pBufHead = MemAlloc(HOST_BUF_SIZE)) == NULL)
return DispErr("CreateCaptureGroup",
"Unable to allocate host RAM I/O buffer");
// Neither has been written to yet.
Vid.BufDataCnt = (U32)0;
Aud.BufDataCnt = (U32)0;
// Create the video stream.
if (!CreateVideoStream())
return FALSE;
// Create the audio stream.
if (!CreateAudioStream())
return FALSE;
// Flush the group to allocate all of the group and stream resources.
if ((AvkRet = AvkGrpFlush(hGrp)) != OK)
return DispAvkErr(AvkRet, "AvkGrpFlush");
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL CreateVideoStream(VOID)
//
//DESCRIPTION:
//
// Create and format a video stream for the capture group's video
// capture buffer.
//
//RETURN:
//
// TRUE on success.
// FALSE on any error (error message box is displayed before exit).
//
//-------------------------------------------------------------------------
static BOOL
CreateVideoStream()
{
// Create the video stream.
if ((AvkRet = AvkVidStrmCreate(Vid.hGrpBuf, 0, &Vid.hStrm)) != OK)
return DispAvkErr(AvkRet, "AvkVidStrmCreate");
// Format the video stream.
Rtv20Args.xLen = Syncs[CaptureSync].xResRTV;
Rtv20Args.yLen = Syncs[CaptureSync].yResVid;
if ((AvkRet = AvkVidStrmFormat(Vid.hStrm,
6,
Syncs[CaptureSync].xResVid,
Syncs[CaptureSync].yResVid,
AVK_YUV9,
Syncs[CaptureSync].FrameRate,
AVK_RTV_2_0,
&Rtv20Args, sizeof(Rtv20Args), sizeof(Rtv20Args),
pVshBuf, VshSize, 64L * 1024L)) != OK)
return DispAvkErr(AvkRet, "AvkVidStrmFormat");
// Free the VSH buffer now that we don't need it any more -
// AvkVidStrmFormat() makes a copy of the VSH data.
MemFree(pVshBuf);
// Create the connectors from the digitizer to the video stream.
// When this connector is enabled, capture data will begin to
// flow from the CS2 board to the stream.
if ((AvkRet = AvkConnCreate(AVK_CONN_DIGITIZER, NULL, Vid.hStrm,
NULL, 0, &View.hConnDigi2Strm)) != OK)
return DispAvkErr(AvkRet,
"AvkConnCreate (Digitizer to Stream)");
// Create the connector from the video stream to the view. When
// this connector is enabled, the captured data will begin to
// flow from the video stream to the view and, if the view is
// also enabled, appear on the screen in the rectangle defined
// in View.DstBox.
if ((AvkRet = AvkConnCreate(Vid.hStrm, NULL, View.hView,
&View.DstBox, AVK_PRE_MONITOR, &View.hConnStrm2View)) != OK)
return DispAvkErr(AvkRet, "AvkConnCreate (Stream to View)");
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL CreateAudioStream(VOID)
//
//DESCRIPTION:
//
// Create and format a audio stream for the capture group's audio
// capture buffer.
//
//RETURN:
//
// TRUE on success.
// FALSE on any error (error message box is displayed before exit).
//
//-------------------------------------------------------------------------
static BOOL
CreateAudioStream()
{
// Create an audio stream.
if ((AvkRet = AvkAudStrmCreate(Aud.hGrpBuf, 0, &Aud.hStrm)) != OK)
return DispAvkErr(AvkRet, "AvkAudStrmCreate");
// Format the audio stream.
if ((AvkRet = AvkAudStrmFormat(Aud.hStrm, FRAME_RATE, AUD_SAMPLE_RATE,
AVK_ADPCM4, AVK_AUD_MIX, NULL, 0, 0)) != OK)
return DispAvkErr(AvkRet, "AvkAudStrmFormat");
// Note that setting audio volume has no effect on a capture stream
// (unless you are also playing back a separate file and want to hear
// both the capture and playback audio together).
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL LoadVshFile()
//
//DESCRIPTION:
//
// Open the standard VSH file that comes with AVK, allocate a block of
// memory to hold it and read it in.
//
//RETURN:
//
// TRUE on success.
// FALSE on error (error messages displayed in this function).
//
//-------------------------------------------------------------------------
static BOOL
LoadVshFile()
{
int fhVsh;
OFSTRUCT Of;
// Open the VSH file. OpenFile will check all directories in the
// PATH environment variable.
if ((fhVsh = OpenFile(VSHFILE_NAME, &Of, OF_READ)) == -1)
return DispErr("LoadVshFile",
"Unable to find the file KE080200.VSH");
VshSize = filelength(fhVsh);
// Range check - we don't want to try to read 0 bytes or a file
// greater than _lread can handle. Reject if VshSize == 0 or
// VshSize > 65535L.
if (!VshSize || VshSize & 0xffff0000)
return DispErr("LoadVshFile", "VSH file too large to load");
// Allocate a buffer to stash the VSH file.
if ((pVshBuf = MemAlloc((WORD)VshSize)) == NULL)
return DispErr("LoadVshFile",
"Unable to allocate VSH file buffer");
// Read the VSH data from the file.
if (_lread(fhVsh, pVshBuf, (WORD)VshSize) != (WORD)VshSize)
return DispErr("LoadVshFile", "Unable to read VSH file");
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL ToggleMonitor(VOID)
//
//DESCRIPTION:
//
// If we are initialized and monitoring is off, turn it on. If
// monitoring is on and we are not capturing, turn it off. We call
// the functions MonitorOn() and MonitorOff() to do the real work.
//
//RETURN:
//
// AVK_ERR_OK (0) on success.
// Non-zero on AVK error returned from MonitorOn() or MonitorOff
//
//-------------------------------------------------------------------------
BOOL
ToggleMonitor()
{
BOOL bRet;
// Call MonitorOn() or MonitorOff() according to the current
// state. Note that we won't turn off monitoring if the
// current state is ST_CAPTURING. Capturing has to be toggled
// off first.
switch (GetState())
{
case ST_INITIALIZED: bRet = MonitorOn(); break;
case ST_MONITORING: bRet = MonitorOff(); break;
default: bRet = TRUE; break;
}
return bRet;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL MonitorOn(VOID)
//
//DESCRIPTION:
//
// Turn on premonitoring.
//
//RETURN:
//
// TRUE on success.
// FALSE on any error (error message box is displayed before exit).
//
//-------------------------------------------------------------------------
static BOOL
MonitorOn()
{
// Enable the connectors from the digitizer to the video stream
// and from the video stream to the view. Video will be
// displayed.
if ((AvkRet = AvkConnEnable(View.hConnDigi2Strm, NOW)) != OK
|| (AvkRet = AvkConnEnable(View.hConnStrm2View, NOW)) != OK)
return DispAvkErr(AvkRet, "AvkConnEnable");
// Turn on audio.
if ((AvkRet = AvkDeviceAudioIn(hDev, AVK_AUD_CAPT_LINE_INPUT,
AVK_MONITOR_ON)) != AVK_ERR_OK)
return DispAvkErr(AvkRet, "AvkDeviceAudioIn");
// State transition to monitoring state.
ToState(ST_MONITORING);
SetClipTimer();
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL MonitorOff(VOID)
//
//DESCRIPTION:
//
// Turn off premonitoring.
//
//RETURN:
//
// TRUE on success.
// FALSE on any error (error message box is displayed before exit).
//
//-------------------------------------------------------------------------
static BOOL
MonitorOff()
{
KillClipTimer();
// Turn off the flow of video by hiding the connectors. AvkConnHide()
// paints the key color (black) into the connector's destination and
// then disables the connector.
if ((AvkRet = AvkConnHide(View.hConnStrm2View, NOW)) != OK
|| (AvkRet = AvkConnHide(View.hConnDigi2Strm, NOW)) != OK)
return DispAvkErr(AvkRet, "AvkConnHide");
#if 0
if ((AvkRet = AvkViewCleanRect(View.hView, &View.DstBox)) != OK)
return DispAvkErr(AvkRet, "AvkViewCleanRect");
#endif
// Turn off audio monitoring.
if ((AvkRet = AvkDeviceAudioIn(hDev, AVK_AUD_CAPT_LINE_INPUT,
AVK_MONITOR_OFF)) != AVK_ERR_OK)
return DispAvkErr(AvkRet, "AvkDeviceAudioIn");
// State transition from monitoring state to initialized state.
ToState(ST_INITIALIZED);
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL GetDevCaps()
//
//DESCRIPTION:
//
// Get the device capabilities from AVK. Use the DviMonitorSync value
// which was extracted from AVK.INI to decide on the AVK View type and
// the x and y resolutions.
//
//RETURN:
//
// TRUE on success.
// FALSE if AvkGetDevCaps() fails or returns an unrecognized
// DviMonitorSync.
//
//-------------------------------------------------------------------------
BOOL
GetDevCaps(VIEW *pView)
{
DVICAPS DevCaps;
// Get the physical screen resolution from the system.
pView->cxScreen = GetSystemMetrics(SM_CXSCREEN);
pView->cyScreen = GetSystemMetrics(SM_CYSCREEN);
// Get the AVK device capabilities which were set in AVK.INI
if ((AvkRet = AvkGetDevCaps(0, sizeof(DevCaps), &DevCaps)) != OK)
return DispAvkErr(AvkRet, "AvkGetDevCaps");
if (DevCaps.DigitizerRevLevel == 0)
return DispErr("GetDevCaps",
"Digitizer needed for capturing - check AVK.INI");
// Interpret DVICAPS data according to our completely arbitrary
// precedence. Since more than one monitor choice can be bitmapped
// in DviMonitorSync, we default in whatever order most suits
// the specific app's needs. In this case, we let VGA take
// precedence over XGA if both are indicated, and either VGA or
// XGA over either PAL or NTSC.
if (DevCaps.DviMonitorSync & 0x10) // VGA
{
pView->cxView = 256;
pView->cyView = 240;
pView->VidType = AVK_VID_VGA_KEYED;
pView->bIsKeyed = TRUE;
}
else if (DevCaps.DviMonitorSync & 0x100) // XGA
{
pView->cxView = 256;
pView->cyView = 192;
pView->VidType = AVK_VID_XGA_KEYED;
pView->bIsKeyed = TRUE;
}
else if (DevCaps.DviMonitorSync & 0x02) // PAL
{
pView->cxView = 306;
pView->cyView = 288;
pView->VidType = AVK_VID_PAL;
}
else if (DevCaps.DviMonitorSync & 0x01) // NTSC
{
pView->cxView = 256;
pView->cyView = 240;
pView->VidType = AVK_VID_NTSC;
}
else
return DispErr("GetDevCaps", "Invalid monitor sync");
// Calculate Screen-To-AVK coordinate conversion deltas.
// We will use these deltas to convert from the native screen
// resolution to the AVK View resolution. For example, given a
// screen resolution of 640x489 and an AVK View of 256x240,
// we convert an X coordinate with the formula:
//
// Xavk = (int)((double)Xscreen * (256.0 / 640.0))
//
pView->xDelta = (double)pView->cxView / (double)pView->cxScreen;
pView->yDelta = (double)pView->cyView / (double)pView->cyScreen;
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL CreateView(pView)
//
//PARMS IN:
//
// VIEW *pView; pointer to View structure
//
//DESCRIPTION:
//
// Create and display an AVK View. The View describes the motion
// video plane plane on the motion video monitor. This view is a
// YUV 9-bit view. The resolution and video type (e.g., VGA, XGA,
// etc.) will be determined by the type of motion video monitor sync
// specified in the AVK.INI file. We extracted this information in
// the function GetDevCaps().
//
//RETURN:
//
// TRUE on success.
// FALSE if an AVK call failed.
//
//-------------------------------------------------------------------------
static BOOL
CreateView(VIEW *pView)
{
// Create the View.
if ((AvkRet = AvkViewCreate(hDev, pView->cxView,
pView->cyView, AVK_YUV9, pView->VidType,
&pView->hView)) != OK)
return DispAvkErr(AvkRet, "AvkViewCreate");
// After creating a View, we display the View. This call actually
// makes the View visible on the monitor. The View is initially
// displayed as a black rectangle.
if ((AvkRet = AvkViewDisplay(hDev, pView->hView, NOW,
AVK_VIEW_DISPLAY_DEFAULT)) != OK)
return DispAvkErr(AvkRet, "AvkViewDisplay");
// Set the destination box for the stream-to-view connector according
// to the coordinates of the main window's client rectangle.
if (!SetDstBox(hwndMain))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL SetDstBox(hwndMain)
//
//PARMS IN:
//
// HWND hwndMain; main window handle
//
//RETURN:
//-------------------------------------------------------------------------
BOOL
SetDstBox(HWND hwndMain)
{
RECT WinRect;
BOX NewDstBox;
GetClientRect(hwndMain, (LPRECT)&WinRect);
ClientToScreen(hwndMain, (LPPOINT)&WinRect);
WinRect.right = WinRect.left + (View.cxScreen >> 1) - 1;
WinRect.bottom = WinRect.top + (View.cyScreen >> 1) -1;
WinRect2AvkBox(&WinRect, &NewDstBox, &View);
if (View.hConnStrm2View)
{
// Hide the connector destination.
if ((AvkRet = AvkConnHide(View.hConnStrm2View, NOW)) != OK)
return DispAvkErr(AvkRet, "AvkConnHide");
// Clean the old rect's area to black.
if ((AvkRet = AvkViewCleanRect(View.hView, &View.DstBox))
!= OK)
return DispAvkErr(AvkRet, "AvkViewCleanRect");
// Reset the destination of the connector to our new box.
if ((AvkRet = AvkConnModSrcDst(View.hConnStrm2View,
NULL, &NewDstBox,
NOW)) != OK)
return DispAvkErr(AvkRet, "AvkConnModSrcDst");
// Enable the connector.
if ((AvkRet = AvkConnEnable(View.hConnStrm2View, NOW)) != OK)
return DispAvkErr(AvkRet, "AvkConnEnable");
}
// Copy the new destination coords into the view's destination box.
COPYBOX(&View.DstBox, &NewDstBox);
return TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// WORD ToState(NewState)
//
//PARMS IN:
//
// WORD NewState; // The new state
//
//DESCRIPTION:
//
// Sets a new state and enables/disables the applicable menu options.
//
//RETURN:
//
// The old state if the state changed or remained the same.
// 0xffff if the new state is an invalid value.
//
//-------------------------------------------------------------------------
WORD
ToState(WORD NewState)
{
WORD OldState;
if (NewState == ST_CAPTURING
|| NewState == ST_MONITORING
|| NewState == ST_INITIALIZED
|| NewState == ST_UNINITIALIZED)
{
if (State != NewState)
{
OldState = State;
State = NewState;
UpdateMenus(State);
return OldState;
}
else
return NewState;
}
return 0xffff;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// BOOL IsState(QueryState)
//
//PARMS IN:
//
// WORD QueryState; a state value
//
//DESCRIPTION:
//
// Checks whether the current state equals the caller's query state.
//
//RETURN:
//
// TRUE if the current state equals the caller's query state.
// FALSE if not.
//
//-------------------------------------------------------------------------
BOOL
IsState(WORD QueryState)
{
return State == QueryState;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// WORD GetState(VOID)
//
//DESCRIPTION:
//
// Returns the current state to the caller.
//
//RETURN:
//
// The current value for State.
//
//-------------------------------------------------------------------------
WORD
GetState()
{
return State;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// VOID SetClipTimer()
//
//DESCRIPTION:
//
//RETURN:
//
//-------------------------------------------------------------------------
VOID
SetClipTimer()
{
CopyList.hConn = View.hConnStrm2View;
CopyList.hwndTarget = hwndMain;
CopyList.ClipCnt = 0;
GetClientRect(hwndMain, (LPRECT)&CopyList.rectTarget);
ClientToScreen(hwndMain, (LPPOINT)&CopyList.rectTarget);
ClientToScreen(hwndMain, (LPPOINT)&CopyList.rectTarget + 1);
lpThunk = MakeProcInstance(ClipTimerProc, hInst);
if (SetTimer(hwndMain, CLIP_TIMER_ID, CLIP_TIMER_INTERVAL, lpThunk))
bClipTimerSet = TRUE;
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// VOID KillClipTimer()
//
//DESCRIPTION:
//
//RETURN:
//
//-------------------------------------------------------------------------
VOID
KillClipTimer()
{
if (bClipTimerSet)
{
KillTimer(hwndMain, CLIP_TIMER_ID);
bClipTimerSet = FALSE;
FreeProcInstance(lpThunk);
}
}
//-------------------------------------------------------------------------
//FUNCTION:
//
// WORD FAR PASCAL TimerClipProc(hwnd, Msg, wParam, lParam)
//
//PARMS IN:
//
// HWND hWnd handle to window specified in SetTimer() call.
// WORD Msg always WM_TIMER
// WORD wParam Timer ID
// LONG lParam address of this function
//
//DESCRIPTION:
//
//
// This function is called by the Windows timer periodically to update
// the connector copylist. It calls UpdateCopyList, which runs the
// Windows Manager's list of open windows and creates a copylist
// to exclude all overlapping regions of our connector's destination
// box.
//
//
//RETURN:
//
// This function always returns 0. The user must respond to the
// error message and close down the application if anything fails.
// Note that it does turn off periodic clipping by leaving the
// re-entry flag bInClipping set to prevent a pileup of repeated
// errors.
//
//-------------------------------------------------------------------------
WORD FAR PASCAL
ClipTimerProc(HWND hWnd, WORD Msg, WORD wParam, LONG lParam)
{
I16 rc;
BOOL bStatus;
static BOOL bInClipping = FALSE;
if (bInClipping)
return 0;
bInClipping = TRUE;
rc = UpdateCopyList(&CopyList, (RECT *)&View.DstBox, View.cxView,
View.cyView, &bStatus);
switch (rc)
{
case AVK_ERR_OK:
break;
case COPY_ERROR:
DispErr("ClipTimerProc", "Error in Clip2Copy");
return 0;
default:
DispAvkErr(rc, "AvkConnCopyList");
return 0;
}
bInClipping = FALSE;
return 0;
}